
using DiLe.Mes.Application.Cloud.Dashboard;
using DiLe.Mes.Application.Cloud.Statistics;
using DiLe.Mes.Application.Common;
using DiLe.Mes.Application.Common.Equipment;
using DiLe.Mes.Application.Common.Mould;
using DiLe.Mes.Application.Handler;
using DiLe.Mes.Cloud.Controllers.Dashboard.Dto;
using DiLe.Mes.Cloud.Controllers.Statistics.Dto;
using DiLe.Mes.Model.Cloud.Dashboard.Equipment;
using DiLe.Mes.Model.Cloud.Dashboard.Statistics;
using DiLe.Mes.Model.Cloud.Statistics;
using DiLe.Mes.Service.Dto;
using MapleLeaf.Core.Excel;
using Microsoft.AspNetCore.Authorization;



namespace DiLe.Mes.Cloud.Controllers.Statistics {
    /// <summary>
    /// 统计
    /// </summary>
    [ApiExplorerSettings(GroupName = ApiCloudGroupConst.Dashboard)]
    public class StatisticsController : ApiBaseController {
        private readonly StatisticsClient _statistics;
        private readonly EquipmentManageClient _equipmentclient;
        private readonly WorkOrderClient _workOrder;
        private readonly MouldInfoClient _mouldInfoClient;
        private readonly IWebHostEnvironment _webHostEnvironment;
        private readonly EquipmentExjosnHandler _handler;
        private readonly EquipmentDashboardClient _dashboardClient;
        /// <summary>
        /// 构造函数
        /// </summary>
        public StatisticsController(StatisticsClient statisticsClient,
                                    EquipmentManageClient equipmentclient,
                                    WorkOrderClient workOrderClient,
                                    MouldInfoClient mouldInfoClient,
                                    IWebHostEnvironment webHostEnvironment,
                                    EquipmentDashboardClient dashboardClient,
                                    EquipmentExjosnHandler handler) {
            _statistics = statisticsClient;
            _equipmentclient = equipmentclient;
            _workOrder = workOrderClient;
            _mouldInfoClient = mouldInfoClient;
            _webHostEnvironment = webHostEnvironment;
            _handler = handler;
            _dashboardClient = dashboardClient;
        }
        #region 品质
        /// <summary>
        /// 获取品质数据统计
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> GetAOIYieldRateStatisticsList(StatisticsParameter parameter) {
            var list = new List<StatisticsDto<AOIYieldRateStatisticsModel>>();

            var dto = await GetAOIYieldRateStatisticsDtoAsync(parameter);
            list.Add(dto);

            return Success(list);
        }
        /// <summary>
        /// 
        /// </summary>
        private async Task<StatisticsDto<AOIYieldRateStatisticsModel>> GetAOIYieldRateStatisticsDtoAsync(StatisticsParameter parameter) {

            var dto = new StatisticsDto<AOIYieldRateStatisticsModel>();

            long orgid = AppHelper.QueryOrgId;

            var typeList = await _equipmentclient.GetEquipmentTypeListAsync();
            var dic = TypeHelper.GetEquipmentTypeDic(typeList);
            var infoList = _equipmentclient.GetEquipmentInfoModelList();


            var whereExp = Expressionable.Create<EquipmentOutputStatisticsEntity>();
            whereExp.And(p => p.Date >= parameter.StartDate);
            whereExp.And(p => p.Date <= parameter.EndDate);
            whereExp.And(p => p.FactoryId == orgid);
            var statisticslist = await _statistics.GetEquipmentOutputStatisticsList(whereExp.ToExpression());
            var swrecordList = await _workOrder.GetStartWorkRecordListAsync(p => p.StartWorkTime >= parameter.StartDate && p.StartWorkTime <= parameter.EndDate);

            var typeids = dic["AOI"];
            var items = new List<AOIYieldRateStatisticsModel>();
            int index = 0;
            foreach (var data in statisticslist) {
                var info = infoList.FirstOrDefault(p => p.EquipmentCode == data.EquipmentCode);
                if (info == null || !typeids.Contains(info.EquipmentTypeId)) {
                    continue;
                }
                var m = data.Adapt<AOIYieldRateStatisticsModel>();
                m.StartCheckNGNo = data.StartCheckNG ?? 0;
                m.EndCheckNGNo = data.EndCheckNG;
                m.NGNumber = data.EndCheckNG - data.StartCheckNG;


                m.StartCheckTimes = data.StartNumber ?? 0;
                m.EndCheckTimes = data.EndNumber;
                m.InspectionQuantity = data.EndNumber - data.StartNumber ?? 0;
                m.YieldQuantity = m.InspectionQuantity - (m.NGNumber ?? 0);
                m.CheckDate = data.Date;
                if (m.YieldQuantity == 0 || m.InspectionQuantity == 0) {
                    m.AOIYieldRate = 0;
                } else {
                    m.AOIYieldRate = Math.Round(m.YieldQuantity / (decimal)m.InspectionQuantity * 100, 1);
                }
                var t = swrecordList.FirstOrDefault(x => x.EquipmentCode == data.EquipmentCode && x.StartWorkTime == data.Date);
                m.OrderCode = t?.OrderCode ?? "";
                m.ProductName = t?.ProductName ?? "";

                items.Add(m);
                m.Id = index;
                index++;
            }
            dto.Type = "AOI";
            dto.DataArr = [.. items.OrderBy(x => x.EquipmentName)];
            var c1_sum = items.Sum(p => p.YieldQuantity);
            var c2_sum = items.Sum(p => p.InspectionQuantity);
            if (c2_sum == 0) {
                dto.Sum = 0;
            } else {
                dto.Sum = Math.Round(c1_sum / (decimal)c2_sum * 100, 1);
            }
            return dto;
        }


        /// <summary>
        /// 导出品质数据统计
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> ExportAOIYieldRateStatistics(StatisticsParameter parameter) {
            List<ExportColumn> dic = [
                new ExportColumn() { Field = "EquipmentCode", Title = "设备编号" },
                new ExportColumn() { Field = "EquipmentName", Title = "设备名称" },
                new ExportColumn() { Field = "OrderCode", Title = "订单编号" },
                new ExportColumn() { Field = "ProductName", Title = "产品名称" },
                new ExportColumn() { Field = "CheckDate", Title = "检验日期" },
                new ExportColumn() { Field = "StartCheckTimes", Title = "起始检验总数" },
                new ExportColumn() { Field = "EndCheckTimes", Title = "结算检验总数" },
                new ExportColumn() { Field = "InspectionQuantity", Title = "检验数量" },
                new ExportColumn() { Field = "StartCheckNGNo", Title = "起始NG总数" },
                new ExportColumn() { Field = "EndCheckNGNo", Title = "结算NG总数" },
                new ExportColumn() { Field = "NGNumber", Title = "NG数量" },
                new ExportColumn() { Field = "YieldQuantity", Title = "良品数量" },
                new ExportColumn() { Field = "AOIYieldRate", Title = "AOI良率(%)", Precision = 2 }
            ];
            var dto = await GetAOIYieldRateStatisticsDtoAsync(parameter);

            var excelFileName = $"品质数据统计({parameter.StartDate:yyyyMMdd}-{parameter.EndDate:yyyyMMdd}).xlsx";

            //导出表头和字段集合
            ExportColumnCollective ecc = new();
            //导出字段集合
            ecc.ExportColumnList = dic;
            //导出表头集合 	 使用list是为了后续可能有多表头合并列的需求，这里只需要单个表头所以一个list就ok了
            ecc.HeaderExportColumnList = [
                 dic
            //new List<ExportColumn>
            //{
            //    new ExportColumn{Title = "子标题A",ColSpan = 1},
            //    new ExportColumn{Title = "子标题B",ColSpan = 1}
            //},
            ];

            // 设置响应头信息
            HttpContext.Response.Headers.AccessControlExposeHeaders = "Content-Disposition";

            byte[] result = Export2Excel.Export(dto.DataArr, ecc, "品质数据统计", false);

            return File(result, "application/octet-stream", excelFileName);

        }
        #endregion
        #region 成本数据
        /// <summary>
        /// 获取成本数据统计
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> GetEquipmentUtilizationRateStatistics(StatisticsParameter parameter) {
            var list = await GetEquipmentUtilizationRateStatisticsDtoAsync(parameter);
            return Success(list);
        }

        /// <summary>
        /// 获取成本数据统计
        /// </summary>
        /// <returns></returns>
        private async Task<List<StatisticsDto<EquipmentUtilizationRateStatisticsModel>>> GetEquipmentUtilizationRateStatisticsDtoAsync(StatisticsParameter parameter) {
            var list = new List<StatisticsDto<EquipmentUtilizationRateStatisticsModel>>();
            var typeList = await _equipmentclient.GetEquipmentTypeListAsync();
            var dic = TypeHelper.GetEquipmentTypeDic(typeList);

            long orgid = AppHelper.QueryOrgId;

            List<EquipmentInfoModel> infoList = await _equipmentclient.GetEquipmentInfoModelListAsync(orgid);

            var whereExp = Expressionable.Create<EquipmentStatisticsEntity>();
            whereExp.And(p => p.Date >= parameter.StartDate);
            whereExp.And(p => p.Date <= parameter.EndDate);
            whereExp.And(p => p.FactoryId == orgid);
            var eqstatistics = await _statistics.GetEquipmentUtilizationRateStatisticsList(whereExp.ToExpression());

            var param = new UtilizationRateParamter {
                Dic = dic,
                Infos = infoList,
                Statisticslist = eqstatistics,
                TypeList = typeList
            };
            if (parameter.Type == "FORMING") {
                var ur = GetEquipmentUtilizationRate(param);
                list.Add(ur);
            } else if (parameter.Type == "TRIM") {
                var trimdto = GetTrimEquipmentUtilizationRate(param);
                list.Add(trimdto);
            } else if (parameter.Type == "AOI") {
                var aoiDto = GetAOIEquipmentUtilizationRate(param);
                list.Add(aoiDto);
            } else {
                var ur = GetEquipmentUtilizationRate(param);
                list.Add(ur);
                var trimdto = GetTrimEquipmentUtilizationRate(param);
                list.Add(trimdto);
                var aoiDto = GetAOIEquipmentUtilizationRate(param);
                list.Add(aoiDto);
            }
            return list;
        }

        /// <summary>
        /// 获取成本数据统计
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> ExportEquipmentUtilizationRateStatistics(StatisticsParameter parameter) {
            List<ExportColumn> dic = [
                new ExportColumn() { Field = "NO", Title = "序号" },
                new ExportColumn() { Field = "EquipmentCode", Title = "设备编号" },
                new ExportColumn() { Field = "EquipmentName", Title = "设备名称" },
                new ExportColumn() { Field = "Classes", Title = "班次" },
                new ExportColumn() { Field = "Date", Title = "日期" },
                new ExportColumn() { Field = "EquipmentStartTime", Title = "开机时间" },
                new ExportColumn() { Field = "EquipmentEndTime", Title = "关机时间" },
                new ExportColumn() { Field = "ActualWorkingHour", Title = "设备实际工时(H)", Precision = 2 },
                new ExportColumn() { Field = "StandardWorkingHour", Title = "设备标准工时(H)", Precision = 2 },
                new ExportColumn() { Field = "UtilizationRate", Title = "设备稼动率(%)" }
            ];
            var list = await GetEquipmentUtilizationRateStatisticsDtoAsync(parameter);

            var typedic = new Dictionary<string, object>() { { "FORMING", "成型机" }, { "TRIM", "切箍边机" }, { "AOI", "AOI" }, { "", "" } };

            var dtDic = new Dictionary<string, List<EquipmentUtilizationRateStatisticsModel>>();
            foreach (var model in list) {
                dtDic.Add($"各{typedic[model.Type]}稼动率", model.DataArr);
            }
            var excelFileName = $"稼动率统计({parameter.StartDate:yyyyMMdd}-{parameter.EndDate:yyyyMMdd}).xlsx";

            //导出表头和字段集合
            ExportColumnCollective ecc = new() {
                //导出字段集合
                ExportColumnList = dic,
                //导出表头集合 	
                //使用list是为了后续可能有多表头合并列的需求，这里只需要单个表头所以一个list就ok了
                HeaderExportColumnList = [dic]
            };
            var bytes = Export2Excel.Export(dtDic, ecc, false);
            // 设置响应头信息
            HttpContext.Response.Headers.AccessControlExposeHeaders = "Content-Disposition";

            return File(bytes, "application/octet-stream", excelFileName);
        }



        /// <summary>
        /// 每日AOI成本数据
        /// </summary>
        /// <returns></returns>
        private static StatisticsDto<EquipmentUtilizationRateStatisticsModel> GetAOIEquipmentUtilizationRate(UtilizationRateParamter paramter) {
            var dto = new StatisticsDto<EquipmentUtilizationRateStatisticsModel>() {
                Type = "AOI"
            };
            var list = paramter.Dic["AOI"];
            var items = new List<EquipmentUtilizationRateStatisticsModel>();
            int index = 0;
            decimal totalHour = 0;
            foreach (var info in paramter.Infos) {
                if (info == null || !list.Contains(info.EquipmentTypeId)) {
                    continue;
                }
                var eslist = paramter.Statisticslist.Where(x => x.DeviceNo == info.EquipmentSign).ToList();
                if (eslist.None()) {
                    var m = new EquipmentUtilizationRateStatisticsModel {
                        ActualWorkingHour = 0,
                        StandardWorkingHour = 0,
                        EquipmentName = info.EquipmentName,
                        EquipmentCode = info.EquipmentCode,
                        Id = index
                    };
                    index++;
                    items.Add(m);
                } else {
                    var day = eslist.FirstOrDefault(x => x.Classes?.StartsWith('8') ?? false);
                    if (day != null) {
                        var m = day.Adapt<EquipmentUtilizationRateStatisticsModel>();
                        m.StandardWorkingHour = info.DayStandardHour == 0 ? (decimal)(10.5) : info.DayStandardHour;
                        if (day.ActualWorkingHour > m.StandardWorkingHour) {
                            m.ActualWorkingHour = m.StandardWorkingHour;
                        } else {
                            m.ActualWorkingHour = day.ActualWorkingHour;
                        }
                        m.UtilizationRate = Math.Round((m.ActualWorkingHour ?? 0) / m.StandardWorkingHour * 100, 1);
                        m.ActualWorkingHour = Math.Round(m.ActualWorkingHour ?? 0, 2);
                        m.EquipmentName = info.EquipmentName;
                        m.EquipmentCode = info.EquipmentCode;
                        m.Id = index;
                        index++;
                        items.Add(m);
                        totalHour += m.StandardWorkingHour;
                    }
                    var night = eslist.FirstOrDefault(x => x.Classes?.StartsWith("20") ?? false);
                    if (night != null) {
                        var m = night.Adapt<EquipmentUtilizationRateStatisticsModel>();
                        m.StandardWorkingHour = info.NightStandardHour == 0 ? (decimal)10.5 : info.NightStandardHour;
                        if (night.ActualWorkingHour > m.StandardWorkingHour) {
                            m.ActualWorkingHour = m.StandardWorkingHour;
                        } else {
                            m.ActualWorkingHour = night.ActualWorkingHour;
                        }
                        m.UtilizationRate = Math.Round((m.ActualWorkingHour ?? 0) / m.StandardWorkingHour * 100, 1);
                        m.ActualWorkingHour = Math.Round(m.ActualWorkingHour ?? 0, 1);
                        m.EquipmentName = info.EquipmentName;
                        m.EquipmentCode = info.EquipmentCode;
                        m.Id = index;
                        index++;
                        items.Add(m);
                        totalHour += m.StandardWorkingHour;
                    }
                }
            }
            dto.DataArr = [.. items.OrderBy(x => x.EquipmentName)];
            dto.Sum = Math.Round(items.Sum(x => x.ActualWorkingHour ?? 0) / totalHour * 100, 1);
            return dto;
        }
        /// <summary>
        /// 每日成本数据
        /// </summary>
        /// <returns></returns>
        private static StatisticsDto<EquipmentUtilizationRateStatisticsModel> GetEquipmentUtilizationRate(UtilizationRateParamter paramter) {
            var dto = new StatisticsDto<EquipmentUtilizationRateStatisticsModel>() {
                Type = "FORMING",
            };
            int index = 0;
            var list = paramter.Dic["成型机"];
            var items = new List<EquipmentUtilizationRateStatisticsModel>();
            decimal totalHour = 0;
            decimal total = 0;
            foreach (var info in paramter.Infos) {
                if (info == null || !list.Contains(info.EquipmentTypeId)) {
                    continue;
                }
                var eslist = paramter.Statisticslist.Where(x => x.DeviceNo == info.EquipmentSign).ToList();
                if (eslist.None()) {
                    var m = new EquipmentUtilizationRateStatisticsModel {
                        ActualWorkingHour = 0,
                        StandardWorkingHour = 0,
                        EquipmentName = info.EquipmentName,
                        EquipmentCode = info.EquipmentCode,
                        Id = index
                    };
                    index++;
                    items.Add(m);
                } else {
                    var day = eslist.FirstOrDefault(x => x.Classes?.StartsWith('8') ?? false);
                    if (day != null) {
                        var m = day.Adapt<EquipmentUtilizationRateStatisticsModel>();
                        m.StandardWorkingHour = info.DayStandardHour;
                        if (day.ActualWorkingHour > info.DayStandardHour) {
                            m.ActualWorkingHour = info.DayStandardHour;
                        } else {
                            m.ActualWorkingHour = day.ActualWorkingHour;
                        }
                        m.UtilizationRate = Math.Round((m.ActualWorkingHour ?? 0) / m.StandardWorkingHour * 100, 1);
                        m.ActualWorkingHour = Math.Round(m.ActualWorkingHour ?? 0, 1);
                        m.EquipmentName = info.EquipmentName;
                        m.EquipmentCode = info.EquipmentCode;
                        m.Id = index;
                        index++;
                        items.Add(m);
                        total += info.DayStandardHour;
                    }
                    var night = eslist.FirstOrDefault(x => x.Classes?.StartsWith("20") ?? false);
                    if (night != null) {
                        var m = night.Adapt<EquipmentUtilizationRateStatisticsModel>();
                        m.StandardWorkingHour = info.NightStandardHour;
                        if (night.ActualWorkingHour > info.NightStandardHour) {
                            m.ActualWorkingHour = info.NightStandardHour;
                        } else {
                            m.ActualWorkingHour = night.ActualWorkingHour;
                        }
                        m.UtilizationRate = Math.Round((m.ActualWorkingHour ?? 0) / m.StandardWorkingHour * 100, 1);
                        m.ActualWorkingHour = Math.Round(m.ActualWorkingHour ?? 0, 2);
                        m.EquipmentName = info.EquipmentName;
                        m.EquipmentCode = info.EquipmentCode;
                        m.Id = index;
                        index++;
                        items.Add(m);
                        total += info.NightStandardHour;
                    }
                }
                totalHour += info.DayStandardHour + info.NightStandardHour;
            }

            dto.DataArr = [.. items.OrderBy(x => x.EquipmentName)];
            var otitems = GetOtherEquipmentUtilizationRate(paramter, ref index, ref totalHour, ref total);
            if (!otitems.None()) {
                dto.DataArr.AddRange(otitems);
            }
            dto.UsageRate = Math.Round(items.Sum(x => x.ActualWorkingHour ?? 0) / totalHour * 100, 1);
            dto.Sum = Math.Round(items.Sum(x => x.ActualWorkingHour ?? 0) / total * 100, 1);
            return dto;
        }
        /// <summary>
        /// 1311
        /// </summary>
        /// <returns></returns>
        private static List<EquipmentUtilizationRateStatisticsModel> GetOtherEquipmentUtilizationRate(UtilizationRateParamter paramter, ref int index, ref decimal totalHour, ref decimal total) {

            var list = paramter.Dic["生产线"];
            var items = new List<EquipmentUtilizationRateStatisticsModel>();
            foreach (var info in paramter.Infos) {
                if (info == null || !list.Contains(info.EquipmentTypeId)) {
                    continue;
                }
                var eslist = paramter.Statisticslist.Where(x => x.DeviceNo == info.EquipmentSign).ToList();
                if (eslist.None()) {
                    var m = new EquipmentUtilizationRateStatisticsModel {
                        ActualWorkingHour = 0,
                        StandardWorkingHour = 0,
                        EquipmentName = info.EquipmentName,
                        EquipmentCode = info.EquipmentCode,
                        Id = index
                    };
                    index++;
                    items.Add(m);
                } else {
                    var day = eslist.FirstOrDefault(x => x.Classes?.StartsWith('8') ?? false);
                    if (day != null) {
                        var m = day.Adapt<EquipmentUtilizationRateStatisticsModel>();
                        m.StandardWorkingHour = info.DayStandardHour > 0 ? info.DayStandardHour : 12;
                        if (day.ActualWorkingHour > m.StandardWorkingHour) {
                            m.ActualWorkingHour = m.StandardWorkingHour;
                        } else {
                            m.ActualWorkingHour = day.ActualWorkingHour;
                        }
                        m.UtilizationRate = Math.Round((m.ActualWorkingHour ?? 0) / m.StandardWorkingHour * 100, 1);
                        m.ActualWorkingHour = Math.Round(m.ActualWorkingHour ?? 0, 2);
                        m.EquipmentName = info.EquipmentName;
                        m.EquipmentCode = info.EquipmentCode;
                        m.Id = index;
                        index++;
                        items.Add(m);
                        total += m.StandardWorkingHour;
                    }
                    var night = eslist.FirstOrDefault(x => x.Classes?.StartsWith("20") ?? false);
                    if (night != null) {
                        var m = night.Adapt<EquipmentUtilizationRateStatisticsModel>();
                        m.StandardWorkingHour = info.NightStandardHour > 0 ? info.NightStandardHour : 12;
                        if (night.ActualWorkingHour > m.StandardWorkingHour) {
                            m.ActualWorkingHour = m.StandardWorkingHour;
                        } else {
                            m.ActualWorkingHour = night.ActualWorkingHour;
                        }
                        m.UtilizationRate = Math.Round((m.ActualWorkingHour ?? 0) / m.StandardWorkingHour * 100, 1);
                        m.ActualWorkingHour = Math.Round(m.ActualWorkingHour ?? 0, 1);
                        m.EquipmentName = info.EquipmentName;
                        m.EquipmentCode = info.EquipmentCode;
                        m.Id = index;
                        index++;
                        items.Add(m);
                        total += m.StandardWorkingHour;
                    }
                }
                totalHour += info.DayStandardHour + info.NightStandardHour;
            }
            return items;
        }

        /// <summary>
        /// 每日切箍边成本数据
        /// </summary>
        /// <returns></returns>
        private static StatisticsDto<EquipmentUtilizationRateStatisticsModel> GetTrimEquipmentUtilizationRate(UtilizationRateParamter paramter) {
            var dto = new StatisticsDto<EquipmentUtilizationRateStatisticsModel>() {
                Type = "TRIM"
            };
            var list = paramter.Dic["冲切机"];
            var items = new List<EquipmentUtilizationRateStatisticsModel>();
            int index = 0;
            decimal totalHour = 0;
            foreach (var info in paramter.Infos) {
                if (info == null || !list.Contains(info.EquipmentTypeId)) {
                    continue;
                }
                var type = paramter.TypeList.FirstOrDefault(p => p.Id == info.EquipmentTypeId);
                var eslist = paramter.Statisticslist.Where(x => x.DeviceNo == info.EquipmentSign).ToList();
                decimal st = type?.StandardWorkingHour ?? 12;
                if (eslist.None()) {
                    var m = new EquipmentUtilizationRateStatisticsModel {
                        ActualWorkingHour = 0,
                        StandardWorkingHour = st,
                        EquipmentName = info.Specification,
                        EquipmentCode = info.EquipmentCode,
                        Id = index
                    };
                    index++;
                    items.Add(m);
                } else {
                    foreach (var es in eslist) {
                        var m = es.Adapt<EquipmentUtilizationRateStatisticsModel>();
                        m.StandardWorkingHour = st;
                        if (es.ActualWorkingHour > st) {
                            m.ActualWorkingHour = st;
                        } else {
                            m.ActualWorkingHour = es.ActualWorkingHour;
                        }
                        m.UtilizationRate = Math.Round((m.ActualWorkingHour ?? 0) / m.StandardWorkingHour * 100, 1);
                        m.ActualWorkingHour = Math.Round(m.ActualWorkingHour ?? 0, 2);
                        m.EquipmentName = info.Specification;
                        m.EquipmentCode = info.EquipmentCode;
                        m.Id = index;
                        index++;
                        items.Add(m);
                        totalHour += st;
                    }
                }
            }
            dto.DataArr = [.. items.OrderBy(x => x.EquipmentName)];
            var t2 = GetTrimEquipmentUtilizationRate2(paramter, ref index);
            if (!t2.None()) {
                dto.DataArr.AddRange(t2);
            }
            dto.Sum = Math.Round(items.Sum(x => x.ActualWorkingHour ?? 0) / totalHour * 100, 2);
            return dto;
        }
        /// <summary>
        /// 每日切箍边成本数据
        /// </summary>
        /// <returns></returns>
        private static List<EquipmentUtilizationRateStatisticsModel> GetTrimEquipmentUtilizationRate2(UtilizationRateParamter paramter, ref int index) {
            var list = paramter.Dic["切边机"];
            var items = new List<EquipmentUtilizationRateStatisticsModel>();

            decimal totalHour = 0;
            foreach (var info in paramter.Infos) {
                if (info == null || !list.Contains(info.EquipmentTypeId)) {
                    continue;
                }
                var type = paramter.TypeList.FirstOrDefault(p => p.Id == info.EquipmentTypeId);
                var eslist = paramter.Statisticslist.Where(x => x.DeviceNo == info.EquipmentSign).ToList();
                var st = type?.StandardWorkingHour ?? 12;
                if (eslist.None()) {
                    var m = new EquipmentUtilizationRateStatisticsModel {
                        ActualWorkingHour = 0,
                        StandardWorkingHour = st,
                        EquipmentName = info.Specification,
                        EquipmentCode = info.EquipmentCode,
                        Id = index
                    };
                    index++;
                    items.Add(m);
                } else {
                    foreach (var es in eslist) {
                        var m = es.Adapt<EquipmentUtilizationRateStatisticsModel>();
                        m.StandardWorkingHour = st;
                        if (es.ActualWorkingHour > st) {
                            m.ActualWorkingHour = st;
                        } else {
                            m.ActualWorkingHour = es.ActualWorkingHour;
                        }
                        m.UtilizationRate = Math.Round((m.ActualWorkingHour ?? 0) / m.StandardWorkingHour * 100, 1);
                        m.ActualWorkingHour = Math.Round(m.ActualWorkingHour ?? 0, 2);
                        m.EquipmentName = info.Specification;
                        m.EquipmentCode = info.EquipmentCode;
                        m.Id = index;
                        index++;
                        items.Add(m);
                        totalHour += st;
                    }
                }
            }
            return items;
        }

        #endregion
        #region 交期

        /// <summary>
        /// 获取交期数据统计
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> GetEquipmentOutputStatisticsList(StatisticsParameter parameter) {
            var list = await GetEquipmentOutputStatisticsListAsync(parameter);
            return Success(list);
        }

        /// <summary>
        /// 获取交期数据统计
        /// </summary>
        /// <returns></returns>
        private async Task<List<StatisticsDto<EquipmentOutputStatisticsModel>>> GetEquipmentOutputStatisticsListAsync(StatisticsParameter parameter) {
            var list = new List<StatisticsDto<EquipmentOutputStatisticsModel>>();
            var typeList = await _equipmentclient.GetEquipmentTypeListAsync();
            var dic = TypeHelper.GetEquipmentTypeDic(typeList);
            var infoList = _equipmentclient.GetEquipmentInfoModelList();

            long orgid = AppHelper.QueryOrgId;
            var whereExp = Expressionable.Create<EquipmentOutputStatisticsEntity>();
            whereExp.And(p => p.Date >= parameter.StartDate);
            whereExp.And(p => p.Date <= parameter.EndDate);
            whereExp.And(p => p.FactoryId == orgid);
            var dataList = await _statistics.GetEquipmentOutputStatisticsList(whereExp.ToExpression());

            var paramer = new StatisticsParamter<EquipmentOutputStatisticsEntity> {
                Dic = dic,
                Infos = infoList,
                Statisticslist = dataList
            };

            if (parameter.Type == "FORMING") {
                var sdto = GetEquipmentStatisticsDto(paramer);
                list.Add(sdto);
            } else if (parameter.Type == "TRIM") {
                var trimdto = GetTrimEquipmentStatisticsDto(paramer);
                list.Add(trimdto);
            } else if (parameter.Type == "AOI") {
                var aoidto = GetAOIEquipmentStatisticsDto(paramer);
                list.Add(aoidto);
            } else if (parameter.Type == "STACKING") {
                var stadto = GetStackingEquipmentStatisticsDto(paramer);
                list.Add(stadto);
            } else {
                var sdto = GetEquipmentStatisticsDto(paramer);
                list.Add(sdto);
                var trimdto = GetTrimEquipmentStatisticsDto(paramer);
                list.Add(trimdto);
                var aoidto = GetAOIEquipmentStatisticsDto(paramer);
                list.Add(aoidto);
                var stadto = GetStackingEquipmentStatisticsDto(paramer);
                list.Add(stadto);
            }
            return list;
        }


        /// <summary>
        /// 获取成本数据统计
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> ExportEquipmentOutputStatistics(StatisticsParameter parameter) {
            List<ExportColumn> dic1 = [
                new ExportColumn() { Field = "NO", Title = "序号" },
                new ExportColumn() { Field = "EquipmentCode", Title = "设备编号" },
                new ExportColumn() { Field = "EquipmentName", Title = "设备名称" },
                new ExportColumn() { Field = "Date", Title = "生产日期" },
                new ExportColumn() { Field = "OrderCode", Title = "订单编号" },
                new ExportColumn() { Field = "", Title = "产品名称" },
                new ExportColumn() { Field = "StartMouldNumber", Title = "起算模次" },
                new ExportColumn() { Field = "EndMouldNumber", Title = "结算模次" },
                new ExportColumn() { Field = "MouldTimes", Title = "当日模次" },
                new ExportColumn() { Field = "MouldCode", Title = "模具编号" },
                new ExportColumn() { Field = "MouldCavityNum", Title = "模具穴数" },
                new ExportColumn() { Field = "OutputQuantity", Title = "产出数量" }
            ];
            List<ExportColumn> dic2 = [
                new ExportColumn() { Field = "NO", Title = "序号" },
                new ExportColumn() { Field = "EquipmentCode", Title = "设备编号" },
                new ExportColumn() { Field = "EquipmentName", Title = "设备名称" },
                new ExportColumn() { Field = "Date", Title = "生产日期" },
                new ExportColumn() { Field = "OrderCode", Title = "订单编号" },
                new ExportColumn() { Field = "", Title = "产品名称" },
                new ExportColumn() { Field = "StartNumber", Title = "起算数量" },
                new ExportColumn() { Field = "EndNumber", Title = "结算数量" },
                new ExportColumn() { Field = "OutputQuantity", Title = "产出数量" }
            ];
            var list = await GetEquipmentOutputStatisticsListAsync(parameter);

            var exemlist = new List<ExportExcelModel>();
            foreach (var model in list) {
                var dic = model.Type == "FORMING" || model.Type == "TRIM" ? dic1 : dic2;
                var item = new ExportExcelModel {
                    Title = $"各{StatisticsParameter.StatisticsTypeDic[model.Type]}产出数"
                };
                item.DtSource.AddRange(model.DataArr);
                item.Columns = new ExportColumnCollective {
                    ExportColumnList = dic,
                    HeaderExportColumnList = [dic]
                };
                exemlist.Add(item);
            }
            var excelFileName = $"稼动率统计({parameter.StartDate:yyyyMMdd}-{parameter.EndDate:yyyyMMdd}).xlsx";

            var bytes = Export2Excel.Export(exemlist);
            // 设置响应头信息
            HttpContext.Response.Headers.AccessControlExposeHeaders = "Content-Disposition";

            return File(bytes, "application/octet-stream", excelFileName);
        }



        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private static StatisticsDto<EquipmentOutputStatisticsModel> GetEquipmentStatisticsDto(StatisticsParamter<EquipmentOutputStatisticsEntity> paramter) {
            var dto = new StatisticsDto<EquipmentOutputStatisticsModel>();
            var list = paramter.Dic["成型机"];
            var items = new List<EquipmentOutputStatisticsModel>();
            int index = 0;
            foreach (var data in paramter.Statisticslist) {
                var info = paramter.Infos.FirstOrDefault(p => p.EquipmentCode == data.EquipmentCode);
                if (info == null || !list.Contains(info.EquipmentTypeId)) {
                    continue;
                }
                var m = data.Adapt<EquipmentOutputStatisticsModel>();
                if (m.EndMouldNumber > 0) {
                    m.MouldTimes = m.EndMouldNumber.Value - m.StartMouldNumber!.Value;
                }
                m.MouldCavityNum = 80;
                m.OutputQuantity = m.MouldTimes * m.MouldCavityNum;
                items.Add(m);
                m.Id = index;
                index++;
            }
            var es1311 = GetOtherEquipmentStatistics(paramter);
            if (!es1311.None()) {
                items.AddRange(es1311);
            }
            dto.Sum = items.Sum(p => p.OutputQuantity);
            dto.DataArr = [.. items.OrderBy(x => x.EquipmentName)];
            dto.Type = "FORMING";
            return dto;
        }
        /// <summary>
        /// 1311
        /// </summary>
        /// <returns></returns>
        private static List<EquipmentOutputStatisticsModel> GetOtherEquipmentStatistics(StatisticsParamter<EquipmentOutputStatisticsEntity> paramter) {

            var list = paramter.Dic["生产线"];
            var items = new List<EquipmentOutputStatisticsModel>();
            int index = 0;
            foreach (var data in paramter.Statisticslist) {
                var info = paramter.Infos.FirstOrDefault(p => p.EquipmentCode == data.EquipmentCode);
                if (info == null || !list.Contains(info.EquipmentTypeId)) {
                    continue;
                }
                var m = data.Adapt<EquipmentOutputStatisticsModel>();
                if (m.EndMouldNumber > 0) {
                    m.MouldTimes = m.EndMouldNumber.Value - m.StartMouldNumber!.Value;
                }
                m.Id = index;
                m.MouldCavityNum = 112;
                m.OutputQuantity = m.MouldTimes * m.MouldCavityNum;
                items.Add(m);
                index++;
            }
            return items;
        }

        /// <summary>
        /// 冲切机
        /// </summary>
        /// <returns></returns>
        private static StatisticsDto<EquipmentOutputStatisticsModel> GetTrimEquipmentStatisticsDto(StatisticsParamter<EquipmentOutputStatisticsEntity> paramter) {
            var dto = new StatisticsDto<EquipmentOutputStatisticsModel>();
            var list = paramter.Dic["冲切机"];
            var items = new List<EquipmentOutputStatisticsModel>();
            int index = 0;
            foreach (var data in paramter.Statisticslist) {
                var info = paramter.Infos.FirstOrDefault(p => p.EquipmentCode == data.EquipmentCode);
                if (info == null || !list.Contains(info.EquipmentTypeId)) {
                    continue;
                }
                var m = data.Adapt<EquipmentOutputStatisticsModel>();
                if (m.EndMouldNumber > 0) {
                    m.MouldTimes = m.EndMouldNumber.Value - m.StartMouldNumber!.Value;
                }
                m.EquipmentName = info.Specification;
                m.MouldCavityNum = 12;
                m.OutputQuantity = m.MouldTimes * m.MouldCavityNum;
                items.Add(m);
                m.Id = index;
                index++;
            }
            dto.DataArr = [.. items.OrderBy(x => x.EquipmentName)];
            var t2 = GetTrimEquipmentStatisticsDto2(paramter, ref index);
            if (!t2.None()) {
                dto.DataArr.AddRange(t2);
            }
            dto.Sum = items.Sum(p => p.OutputQuantity);
            dto.Type = "TRIM";
            return dto;
        }
        /// <summary>
        /// 切边机
        /// </summary>
        /// <returns></returns>
        private static List<EquipmentOutputStatisticsModel> GetTrimEquipmentStatisticsDto2(StatisticsParamter<EquipmentOutputStatisticsEntity> paramter, ref int index) {

            var list = paramter.Dic["切边机"];
            var items = new List<EquipmentOutputStatisticsModel>();
            foreach (var data in paramter.Statisticslist) {
                var info = paramter.Infos.FirstOrDefault(p => p.EquipmentCode == data.EquipmentCode);
                if (info == null || !list.Contains(info.EquipmentTypeId)) {
                    continue;
                }
                var m = data.Adapt<EquipmentOutputStatisticsModel>();
                if (m.EndMouldNumber > 0) {
                    m.MouldTimes = m.EndMouldNumber.Value - m.StartMouldNumber!.Value;
                }
                m.EquipmentName = info.Specification;
                m.MouldCavityNum = 20;
                m.OutputQuantity = m.MouldTimes * m.MouldCavityNum;
                items.Add(m);
                m.Id = index;
                index++;
            }
            return items;
        }

        /// <summary>
        /// AOI
        /// </summary>
        /// <returns></returns>
        private static StatisticsDto<EquipmentOutputStatisticsModel> GetAOIEquipmentStatisticsDto(StatisticsParamter<EquipmentOutputStatisticsEntity> paramter) {
            var dto = new StatisticsDto<EquipmentOutputStatisticsModel>();
            var list = paramter.Dic["AOI"];
            var items = new List<EquipmentOutputStatisticsModel>();
            int index = 0;
            foreach (var data in paramter.Statisticslist) {
                var info = paramter.Infos.FirstOrDefault(p => p.EquipmentCode == data.EquipmentCode);
                if (info == null || !list.Contains(info.EquipmentTypeId)) {
                    continue;
                }
                var m = data.Adapt<EquipmentOutputStatisticsModel>();
                if (m.EndNumber > 0) {
                    m.OutputQuantity = m.EndNumber.Value - m.EndCheckNG - (m.StartNumber!.Value - m.StartCheckNG) ?? 0;
                }
                items.Add(m);
                m.Id = index;
                index++;
            }
            dto.Sum = items.Sum(p => p.EndCheckNG - p.StartCheckNG ?? 0);
            dto.DataArr = [.. items.OrderBy(x => x.EquipmentName)];
            dto.Type = "AOI";
            return dto;
        }

        /// <summary>
        /// 堆叠机
        /// </summary>
        /// <returns></returns>
        private static StatisticsDto<EquipmentOutputStatisticsModel> GetStackingEquipmentStatisticsDto(StatisticsParamter<EquipmentOutputStatisticsEntity> paramter) {
            var dto = new StatisticsDto<EquipmentOutputStatisticsModel>();
            var list = paramter.Dic["生产线"];
            var items = new List<EquipmentOutputStatisticsModel>();
            int index = 0;
            foreach (var data in paramter.Statisticslist) {
                var info = paramter.Infos.FirstOrDefault(p => p.EquipmentCode == data.EquipmentCode);
                if (info == null || !list.Contains(info.EquipmentTypeId)) {
                    continue;
                }
                var m = data.Adapt<EquipmentOutputStatisticsModel>();
                if (m.EndNumber > 0) {
                    m.OutputQuantity = m.EndNumber.Value - m.StartNumber!.Value;
                }
                items.Add(m);
                m.Id = index;
                index++;
            }
            dto.Sum = items.Sum(p => p.OutputQuantity);
            dto.DataArr = [.. items.OrderBy(x => x.EquipmentName)];
            dto.Type = "STACKING";
            return dto;
        }
        #endregion

        #region PLC 统计信息
        /// <summary>
        /// 流量表
        /// </summary>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<ApiResult<List<FMPointStatisticsEntity>>> GetFMPointStatisticsList(PointStatisticsParameter parameter) {
            var wxp = Expressionable.Create<FMPointStatisticsEntity>();
            wxp.And(p => p.FactoryId == AppHelper.QueryOrgId);
            wxp.And(p => SqlFunc.ToDate(p.Date) >= parameter.StartDate);
            wxp.And(p => SqlFunc.ToDate(p.Date) <= parameter.EndDate);
            var list = await _statistics.GetFMPointStatisticsListAsync(wxp.ToExpression());
            return Success(list);
        }
        /// <summary>
        /// 导出流量表
        /// </summary>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<IActionResult> ExportFMPointStatisticsList(PointStatisticsParameter parameter) {
            List<ExportColumn> dic = [
                new ExportColumn() { Field = "Date", Title = "采集日期" },
                new ExportColumn() { Field = "Name", Title = "设备名称" },
                new ExportColumn() { Field = "Type", Title = "设备类型" },
                new ExportColumn() { Field = "FlowRate", Title = "累积流量(M3)" }
            ];
            var wxp = Expressionable.Create<FMPointStatisticsEntity>();
            wxp.And(p => p.FactoryId == AppHelper.QueryOrgId);
            wxp.And(p => SqlFunc.ToDate(p.Date) >= parameter.StartDate);
            wxp.And(p => SqlFunc.ToDate(p.Date) <= parameter.EndDate);
            var list = await _statistics.GetFMPointStatisticsListAsync(wxp.ToExpression());


            var excelFileName = $"流量表采集数据({parameter.StartDate:yyyyMMdd}-{parameter.EndDate:yyyyMMdd}).xlsx";
            var ccv = new ExportColumnCollective() { ExportColumnList = dic, HeaderExportColumnList = [dic] };
            var bytes = Export2Excel.Export(list, ccv, "流量表采集数据");

            // 设置响应头信息
            HttpContext.Response.Headers.AccessControlExposeHeaders = "Content-Disposition";

            return File(bytes, "application/octet-stream", excelFileName);
        }

        /// <summary>
        /// 电能表
        /// </summary>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<ApiResult<List<EMPointStatisticsEntity>>> GetEMPointStatisticsList(PointStatisticsParameter parameter) {
            var wxp = Expressionable.Create<EMPointStatisticsEntity>();
            wxp.And(p => p.FactoryId == AppHelper.QueryOrgId);
            wxp.And(p => SqlFunc.ToDate(p.Date) >= parameter.StartDate);
            wxp.And(p => SqlFunc.ToDate(p.Date) <= parameter.EndDate);
            var list = await _statistics.GetEMPointStatisticsListAsync(wxp.ToExpression());
            return Success(list);
        }
        /// <summary>
        /// 导出电能表
        /// </summary>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<IActionResult> ExportEMPointStatisticsList(PointStatisticsParameter parameter) {
            List<ExportColumn> dic = [
                new ExportColumn() { Field = "Date", Title = "采集日期" },
                new ExportColumn() { Field = "Name", Title = "设备名称" },
                new ExportColumn() { Field = "Type", Title = "设备类型" },
                new ExportColumn() { Field = "FlowRate", Title = "累计电能(KWH)" }
            ];
            var wxp = Expressionable.Create<EMPointStatisticsEntity>();
            wxp.And(p => p.FactoryId == AppHelper.QueryOrgId);
            wxp.And(p => SqlFunc.ToDate(p.Date) >= parameter.StartDate);
            wxp.And(p => SqlFunc.ToDate(p.Date) <= parameter.EndDate);
            var list = await _statistics.GetEMPointStatisticsListAsync(wxp.ToExpression());


            var excelFileName = $"电能表采集数据({parameter.StartDate:yyyyMMdd}-{parameter.EndDate:yyyyMMdd}).xlsx";

            var ccv = new ExportColumnCollective() { ExportColumnList = dic, HeaderExportColumnList = [dic] };

            var bytes = Export2Excel.Export(list, ccv, "电能表采集数据");

            // 设置响应头信息
            HttpContext.Response.Headers.AccessControlExposeHeaders = "Content-Disposition";

            return File(bytes, "application/octet-stream", excelFileName);
        }

        #region AOI-PLC统计信息
        /// <summary>
        /// AOI-PLC统计信息
        /// </summary>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<ApiResult<List<CloudAOIPointInfoModel>>> GetAOIPointStatisticsList(PointStatisticsParameter parameter) {
            var list = await GetAOIPointStatisticsListAsync(parameter);
            return Success(list);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        private async Task<List<CloudAOIPointInfoModel>> GetAOIPointStatisticsListAsync(PointStatisticsParameter parameter) {
            var list = new List<CloudAOIPointInfoModel>();
            var wxp = Expressionable.Create<CloudAOIPointInfoEntity>();
            wxp.And(p => p.FactoryId == AppHelper.QueryOrgId);
            wxp.And(p => SqlFunc.ToDate(p.AcquisitionTime) >= parameter.StartDate);
            wxp.And(p => SqlFunc.ToDate(p.AcquisitionTime) <= parameter.EndDate);
            var datalist = await _dashboardClient.GetAOIPointInfoListAsync(wxp.ToExpression());

            var codeList = datalist.Where(p => !p.DeviceNo.IsNullOrEmpty()).Select(x => x.DeviceNo).Distinct().ToList();
            var temps = await _equipmentclient.GetEquipmentRegisterListAsync(p => codeList.Contains(p.EquipmentSign));
            var registerInfolist = await _handler.GetEquipmentRegisterExjosn(temps);

            foreach (var item in datalist) {
                var info = registerInfolist?.FirstOrDefault(p => p.Model.EquipmentSign == item.DeviceNo);
                if (info == null) {
                    continue;
                }
                var model = item.Adapt<CloudAOIPointInfoModel>();
                model.EquipmentName = info?.Equipment.Name ?? "";
                model.EquipmentCode = info?.Equipment.Code ?? "";
                model.Specification = info?.Equipment.Specification ?? "";
                model.EquipmentPosition = info?.Equipment.ExtJson["PositionName"]?.ToString() ?? "";
                model.FactoryName = info?.Equipment.ExtJson["FactoryName"]?.ToString() ?? "";
                model.EquipmentType = info?.Equipment.ExtJson["TypeName"]?.ToString() ?? "";
                list.Add(model!);
            }
            return list;
        }
        /// <summary>
        /// 导出AOI-PLC统计信息
        /// </summary>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<IActionResult> ExportAOIPointStatisticsList(PointStatisticsParameter parameter) {
            List<ExportColumn> aoiheaderrows = CommonHelper.GetAOIHeaderRows();

            var list = await GetAOIPointStatisticsListAsync(parameter);

            var excelFileName = $"AOI-PLC统计({parameter.StartDate:yyyyMMdd}-{parameter.EndDate:yyyyMMdd}).xlsx";

            //导出表头和字段集合
            ExportColumnCollective ecc = new();
            //导出字段集合
            ecc.ExportColumnList = aoiheaderrows;
            //导出表头集合 	 使用list是为了后续可能有多表头合并列的需求，这里只需要单个表头所以一个list就ok了
            ecc.HeaderExportColumnList = [
                 aoiheaderrows
            ];
            byte[] result = Export2Excel.Export(list, ecc, "AOI-PLC统计", false);
            // 设置响应头信息
            HttpContext.Response.Headers.AccessControlExposeHeaders = "Content-Disposition";

            return File(result, "application/octet-stream", excelFileName);
        }

        #endregion
        #region 切箍边-PLC统计信息
        /// <summary>
        /// 切箍边-PLC统计信息
        /// </summary>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<ApiResult<List<CloudTrimPointInfoModel>>> GetTrimPointStatisticsList(PointStatisticsParameter parameter) {
            var list = await GetTrimPointStatisticsListAsync(parameter);
            return Success(list);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        private async Task<List<CloudTrimPointInfoModel>> GetTrimPointStatisticsListAsync(PointStatisticsParameter parameter) {
            var list = new List<CloudTrimPointInfoModel>();
            var wxp = Expressionable.Create<CloudTrimPointInfoEntity>();
            wxp.And(p => p.FactoryId == AppHelper.QueryOrgId);
            wxp.And(p => SqlFunc.ToDate(p.AcquisitionTime) >= parameter.StartDate);
            wxp.And(p => SqlFunc.ToDate(p.AcquisitionTime) <= parameter.EndDate);
            var datalist = await _dashboardClient.GetTrimlPointInfoListAsync(wxp.ToExpression());

            var codeList = datalist.Where(p => !p.DeviceNo.IsNullOrEmpty()).Select(x => x.DeviceNo).Distinct().ToList();
            var temps = await _equipmentclient.GetEquipmentRegisterListAsync(p => codeList.Contains(p.EquipmentSign));
            var registerInfolist = await _handler.GetEquipmentRegisterExjosn(temps);

            foreach (var item in datalist) {
                var info = registerInfolist?.FirstOrDefault(p => p.Model.EquipmentSign == item.DeviceNo);
                if (info == null) {
                    continue;
                }
                var model = item.Adapt<CloudTrimPointInfoModel>();
                model.EquipmentName = info?.Equipment.Name ?? "";
                model.EquipmentCode = info?.Equipment.Code ?? "";
                model.Specification = info?.Equipment.Specification ?? "";
                model.EquipmentPosition = info?.Equipment.ExtJson["PositionName"]?.ToString() ?? "";
                model.FactoryName = info?.Equipment.ExtJson["FactoryName"]?.ToString() ?? "";
                model.EquipmentType = info?.Equipment.ExtJson["TypeName"]?.ToString() ?? "";
                list.Add(model!);
            }
            return list;
        }
        /// <summary>
        /// 导出切箍边-PLC统计信息
        /// </summary>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<IActionResult> ExportTrimPointStatisticsList(PointStatisticsParameter parameter) {
            List<ExportColumn> aoiheaderrows = CommonHelper.GetTrimHeaderRows();

            var list = await GetTrimPointStatisticsListAsync(parameter);

            var excelFileName = $"切箍边-PLC统计({parameter.StartDate:yyyyMMdd}-{parameter.EndDate:yyyyMMdd}).xlsx";

            //导出表头和字段集合
            ExportColumnCollective ecc = new();
            //导出字段集合
            ecc.ExportColumnList = aoiheaderrows;
            //导出表头集合 	 使用list是为了后续可能有多表头合并列的需求，这里只需要单个表头所以一个list就ok了
            ecc.HeaderExportColumnList = [
                 aoiheaderrows
            ];
            byte[] result = Export2Excel.Export(list, ecc, "切箍边-PLC统计", false);
            // 设置响应头信息
            HttpContext.Response.Headers.AccessControlExposeHeaders = "Content-Disposition";

            return File(result, "application/octet-stream", excelFileName);
        }

        #endregion
        #region 成型机-PLC统计信息
        /// <summary>
        /// 成型机-PLC统计信息
        /// </summary>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<ApiResult<List<CloudPointInfoModel>>> GetFormingPointStatisticsList(PointStatisticsParameter parameter) {
            var list = await GetFormingPointStatisticsListAsync(parameter);
            return Success(list);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        private async Task<List<CloudPointInfoModel>> GetFormingPointStatisticsListAsync(PointStatisticsParameter parameter) {
            var list = new List<CloudPointInfoModel>();
            var wxp = Expressionable.Create<CloudPointInfoEntity>();
            wxp.And(p => p.FactoryId == AppHelper.QueryOrgId);
            wxp.And(p => SqlFunc.ToDate(p.AcquisitionTime) >= parameter.StartDate);
            wxp.And(p => SqlFunc.ToDate(p.AcquisitionTime) <= parameter.EndDate);
            var datalist = await _dashboardClient.GetPointInfoListAsync(wxp.ToExpression());

            var codeList = datalist.Where(p => !p.DeviceNo.IsNullOrEmpty()).Select(x => x.DeviceNo).Distinct().ToList();
            var temps = await _equipmentclient.GetEquipmentRegisterListAsync(p => codeList.Contains(p.EquipmentSign));
            var registerInfolist = await _handler.GetEquipmentRegisterExjosn(temps);

            foreach (var item in datalist) {
                var info = registerInfolist?.FirstOrDefault(p => p.Model.EquipmentSign == item.DeviceNo);
                if (info == null) {
                    continue;
                }
                var model = item.Adapt<CloudPointInfoModel>();
                model.EquipmentName = info?.Equipment.Name ?? "";
                model.EquipmentCode = info?.Equipment.Code ?? "";
                model.Specification = info?.Equipment.Specification ?? "";
                model.EquipmentPosition = info?.Equipment.ExtJson["PositionName"]?.ToString() ?? "";
                model.FactoryName = info?.Equipment.ExtJson["FactoryName"]?.ToString() ?? "";
                model.EquipmentType = info?.Equipment.ExtJson["TypeName"]?.ToString() ?? "";
                //左侧热压下模温度
                if (!model.LeftUpperTemp.IsNullOrEmpty()) {
                    var arr = model.LeftUpperTemp.Split(",");
                    if (arr.Length > 0) {
                        model.LeftUpperTemp1 = arr[0];
                    }
                    if (arr.Length > 1) {
                        model.LeftUpperTemp2 = arr[1];
                    }
                    if (arr.Length > 2) {
                        model.LeftUpperTemp3 = arr[2];
                    }
                    if (arr.Length > 3) {
                        model.LeftUpperTemp4 = arr[3];
                    }
                }
                //左侧热压下模温度
                if (!model.LeftDownTemp.IsNullOrEmpty()) {
                    var arr = model.LeftDownTemp.Split(",");
                    if (arr.Length > 0) {
                        model.LeftDownTemp1 = arr[0];
                    }
                    if (arr.Length > 1) {
                        model.LeftDownTemp2 = arr[1];
                    }
                    if (arr.Length > 2) {
                        model.LeftDownTemp3 = arr[2];
                    }
                    if (arr.Length > 3) {
                        model.LeftDownTemp4 = arr[3];
                    }
                }
                //右侧热压上模温度
                if (!model.RightUpperTemp.IsNullOrEmpty()) {
                    var arr = model.RightUpperTemp.Split(",");
                    if (arr.Length > 0) {
                        model.RightUpperTemp1 = arr[0];
                    }
                    if (arr.Length > 1) {
                        model.RightUpperTemp2 = arr[1];
                    }
                    if (arr.Length > 2) {
                        model.RightUpperTemp3 = arr[2];
                    }
                    if (arr.Length > 3) {
                        model.RightUpperTemp4 = arr[3];
                    }
                }
                //右侧热压下模温度
                if (!model.RightDownTemp.IsNullOrEmpty()) {
                    var arr = model.RightDownTemp.Split(",");
                    if (arr.Length > 0) {
                        model.RightDownTemp1 = arr[0];
                    }
                    if (arr.Length > 1) {
                        model.RightDownTemp2 = arr[1];
                    }
                    if (arr.Length > 2) {
                        model.RightDownTemp3 = arr[2];
                    }
                    if (arr.Length > 3) {
                        model.RightDownTemp4 = arr[3];
                    }
                }
                list.Add(model!);
            }
            return list;
        }
        /// <summary>
        /// 导出 成型机-PLC统计信息
        /// </summary>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<IActionResult> ExportFormingPointStatisticsList(PointStatisticsParameter parameter) {
            List<ExportColumn> aoiheaderrows = CommonHelper.GetFormingHeaderRows();

            var list = await GetTrimPointStatisticsListAsync(parameter);

            var excelFileName = $"成型机--PLC统计({parameter.StartDate:yyyyMMdd}-{parameter.EndDate:yyyyMMdd}).xlsx";

            //导出表头和字段集合
            ExportColumnCollective ecc = new();
            //导出字段集合
            ecc.ExportColumnList = aoiheaderrows;
            //导出表头集合 	 使用list是为了后续可能有多表头合并列的需求，这里只需要单个表头所以一个list就ok了
            ecc.HeaderExportColumnList = [
                 aoiheaderrows
            ];
            byte[] result = Export2Excel.Export(list, ecc, "成型机--PLC统计", false);
            // 设置响应头信息
            HttpContext.Response.Headers.AccessControlExposeHeaders = "Content-Disposition";

            return File(result, "application/octet-stream", excelFileName);
        }

        #endregion
        #region 1311成型机-PLC统计信息
        /// <summary>
        /// 1311成型机-PLC统计信息
        /// </summary>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<ApiResult<List<CloudOtherPointInfoModel>>> GetOtherPointStatisticsList(PointStatisticsParameter parameter) {
            var list = await GetOtherPointStatisticsListAsync(parameter);
            return Success(list);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        private async Task<List<CloudOtherPointInfoModel>> GetOtherPointStatisticsListAsync(PointStatisticsParameter parameter) {
            var list = new List<CloudOtherPointInfoModel>();
            DateTime start = new DateTime(parameter.StartDate.Year, parameter.StartDate.Month, parameter.StartDate.Day);
            DateTime end = new DateTime(parameter.EndDate.Year, parameter.EndDate.Month, parameter.EndDate.Day).AddDays(1).AddSeconds(-1);

            var wxp = Expressionable.Create<CloudOtherPointInfoEntity>();
            wxp.And(p => p.FactoryId == AppHelper.QueryOrgId);
            wxp.And(p => SqlFunc.ToDate(p.AcquisitionTime) >= start);
            wxp.And(p => SqlFunc.ToDate(p.AcquisitionTime) <= end);
            var datalist = await _dashboardClient.Get1311PointInfoListAsync(wxp.ToExpression());

            var codeList = datalist.Where(p => !p.DeviceNo.IsNullOrEmpty()).Select(x => x.DeviceNo).Distinct().ToList();
            var temps = await _equipmentclient.GetEquipmentRegisterListAsync(p => codeList.Contains(p.EquipmentSign));
            var registerInfolist = await _handler.GetEquipmentRegisterExjosn(temps);

            foreach (var item in datalist) {
                var info = registerInfolist?.FirstOrDefault(p => p.Model.EquipmentSign == item.DeviceNo);
                if (info == null) {
                    continue;
                }
                var model = item.Adapt<CloudOtherPointInfoModel>();
                model.EquipmentName = info?.Equipment.Name ?? "";
                model.EquipmentCode = info?.Equipment.Code ?? "";
                model.Specification = info?.Equipment.Specification ?? "";
                model.EquipmentPosition = info?.Equipment.ExtJson["PositionName"]?.ToString() ?? "";
                model.FactoryName = info?.Equipment.ExtJson["FactoryName"]?.ToString() ?? "";
                model.EquipmentType = info?.Equipment.ExtJson["TypeName"]?.ToString() ?? "";


                //左侧热压下模温度
                if (!model.LeftUpperTemp.IsNullOrEmpty()) {
                    var arr = model.LeftUpperTemp.Split(",");
                    if (arr.Length > 0) {
                        model.LeftUpperTemp1 = arr[0];
                    }
                    if (arr.Length > 1) {
                        model.LeftUpperTemp2 = arr[1];
                    }
                    if (arr.Length > 2) {
                        model.LeftUpperTemp3 = arr[2];
                    }
                    if (arr.Length > 3) {
                        model.LeftUpperTemp4 = arr[3];
                    }
                }
                //左侧热压下模温度
                if (!model.LeftDownTemp.IsNullOrEmpty()) {
                    var arr = model.LeftDownTemp.Split(",");
                    if (arr.Length > 0) {
                        model.LeftDownTemp1 = arr[0];
                    }
                    if (arr.Length > 1) {
                        model.LeftDownTemp2 = arr[1];
                    }
                    if (arr.Length > 2) {
                        model.LeftDownTemp3 = arr[2];
                    }
                    if (arr.Length > 3) {
                        model.LeftDownTemp4 = arr[3];
                    }
                }
                //右侧热压上模温度
                if (!model.RightUpperTemp.IsNullOrEmpty()) {
                    var arr = model.RightUpperTemp.Split(",");
                    if (arr.Length > 0) {
                        model.RightUpperTemp1 = arr[0];
                    }
                    if (arr.Length > 1) {
                        model.RightUpperTemp2 = arr[1];
                    }
                    if (arr.Length > 2) {
                        model.RightUpperTemp3 = arr[2];
                    }
                    if (arr.Length > 3) {
                        model.RightUpperTemp4 = arr[3];
                    }
                }
                //右侧热压下模温度
                if (!model.RightDownTemp.IsNullOrEmpty()) {
                    var arr = model.RightDownTemp.Split(",");
                    if (arr.Length > 0) {
                        model.RightDownTemp1 = arr[0];
                    }
                    if (arr.Length > 1) {
                        model.RightDownTemp2 = arr[1];
                    }
                    if (arr.Length > 2) {
                        model.RightDownTemp3 = arr[2];
                    }
                    if (arr.Length > 3) {
                        model.RightDownTemp4 = arr[3];
                    }
                }

                list.Add(model!);
            }
            return list;
        }
        /// <summary>
        /// 导出1311成型机-PLC统计信息
        /// </summary>
        /// <returns></returns>
        [HttpPost, AllowAnonymous]
        public async Task<IActionResult> ExportOtherPointStatisticsList(PointStatisticsParameter parameter) {
            List<ExportColumn> headerrows = CommonHelper.GetOtherHeaderRows();

            var list = await GetOtherPointStatisticsListAsync(parameter);

            var excelFileName = $"1311成型机--PLC统计({parameter.StartDate:yyyyMMdd}-{parameter.EndDate:yyyyMMdd}).xlsx";

            //导出表头和字段集合
            ExportColumnCollective ecc = new();
            //导出字段集合
            ecc.ExportColumnList = headerrows;
            //导出表头集合 	 使用list是为了后续可能有多表头合并列的需求，这里只需要单个表头所以一个list就ok了
            ecc.HeaderExportColumnList = [
                 headerrows
            ];
            byte[] result = Export2Excel.Export(list, ecc, "1311成型机--PLC统计", false);
            // 设置响应头信息
            HttpContext.Response.Headers.AccessControlExposeHeaders = "Content-Disposition";

            return File(result, "application/octet-stream", excelFileName);
        }

        #endregion
        #endregion
    }
}